<template>
    <div style="height: 100%; overflow-y: auto">
        <a-table
            :rowKey="record => `id-${record.id}--parentId-${record.parentId}`"
            :columns="columns"
            :data-source="tableData"
            :loading="tableLoading"
            :pagination="false"
            class="custom-table table-style-primary"
            :scroll="{ y: true }"
            :indentSize="20"
            :expandedRowKeys="expandedRowKeys"
            @expandedRowsChange="expandedRowsChange"
        >
            <template slot="operate" slot-scope="text, record">
                <span class="primary-color" @click="openSubOperateModal(record)">添加下级</span>
                <a-divider type="vertical" />
                <span class="primary-color" @click="openRowOperateModal(record)">编辑</span>
                <a-divider type="vertical" v-if="!record.children || !record.children.length" />
                <a-popconfirm title="确定删除吗?" ok-text="是" cancel-text="否" @confirm="del(record.id)">
                    <span v-if="!record.children || !record.children.length" class="danger-color">删除</span>
                </a-popconfirm>
            </template>
        </a-table>
        <modal
            v-if="isOpenOperateModal"
            :currRow="currRow"
            :parentRow="parentRow"
            :isShowModal.sync="isOpenOperateModal"
            :modalType="modalType"
            :menuOptions="[...tableData]"
            @updateData="getTreeNodes"
        />
    </div>
</template>

<script>
import { cloneDeep, getFinalPageNum, getPIds } from '@/utils/methods'
import { Table, Popconfirm } from 'ant-design-vue'
import modal from './modal'
import { areaRestApi, messageRestApi } from '@/common/api/setting'

export default {
    name: 'areaManage',
    components: {
        ATable: Table,
        APopconfirm: Popconfirm,
        modal,
    },
    data() {
        return {
            // modal
            isOpenOperateModal: false,
            modalType: -1,
            currRow: undefined,
            parentRow: undefined,
            // table

            cloneDeep,
            tableData: [],
            columns: [
                {
                    title: '名称',
                    dataIndex: 'name',
                },
                {
                    title: '编码',
                    dataIndex: 'code',
                },
                {
                    title: '别名',
                    dataIndex: 'abbreviation',
                },
                // areaLevel 级别：0-国；1-省；2-市；3-区县；4-园区
                // areaType 类型：1-行政区划；2-园区
                {
                    title: '级别',
                    dataIndex: 'areaLevel',
                    customRender: text => {
                        switch (text) {
                            case 0:
                                return '国'
                            case 1:
                                return '省'
                            case 2:
                                return '市'
                            case 3:
                                return '区县'
                            case 4:
                                return '园区'
                            default:
                                return ''
                        }
                    },
                },
                // {
                //     title: '类型',
                //     dataIndex: 'areaType',
                //     customRender: text => {
                //         switch (text) {
                //             case 1:
                //                 return '行政区划'
                //             case 2:
                //                 return '园区'
                //             default:
                //                 return ''
                //         }
                //     },
                // },
                {
                    title: '操作',
                    dataIndex: 'operate',
                    scopedSlots: { customRender: 'operate' },
                    width: 200,
                },
            ],
            tableLoading: false,
            expandedRowKeys: [],
            // filter
            filterComponentsData: [
                {
                    type: 'input',
                    searchKey: 'name',
                    antdApi: {
                        placeholder: '搜索行政区划',
                    },
                },
            ],
            searchParams: {
                name: '',
            },
        }
    },
    watch: {},
    mounted() {
        this.getTreeNodes().then(() => {
            this.getDefaultExpand()
        })
    },
    methods: {
        openRowOperateModal(row) {
            this.currRow = row
            this.parentRow = null
            this.isOpenOperateModal = true
        },
        openSubOperateModal(row) {
            this.currRow = null
            this.parentRow = row
            this.isOpenOperateModal = true
        },
        openModal(record, modalType) {
            this.modalType = modalType
            this.currRow = record
            this.isShowModal = true
        },
        getDefaultExpand() {
            this.expandedRowKeys = []
            for (let i = 0; i < this.tableData.length; i++) {
                const { id, children, parentId } = this.tableData[i]
                if (children && children.length) {
                    this.expandedRowKeys.push(`id-${id}--parentId-${parentId}`)
                    break
                }
            }
        },
        async del(id) {
            const res = await areaRestApi.del({ id })
            res.code == 200 ? this.$message.success(`删除行政区成功`) : this.$message.error(`删除行政区失败`)
            await this.getTreeNodes()
        },
        async getTreeNodes() {
            this.tableLoading = true

            var res = await areaRestApi.get()

            this.tableData = this.buildTree(res.data, 1)

            this.tableLoading = false
        },
        expandedRowsChange(expandedRowKeys) {
            const currKey = expandedRowKeys.slice(-1)[0]
            // 从expandedRowKeys移除与当前点击节点父级相同的节点 收起上一步相同级别的节点
            if (currKey) {
                const currPId = currKey.split('--')[1].split('-')[1]
                for (let i = expandedRowKeys.length - 1; i >= 0; i--) {
                    const pId = expandedRowKeys[i].split('--')[1].split('-')[1]
                    if (currPId === pId && expandedRowKeys[i] !== currKey) {
                        expandedRowKeys.splice(i, 1)
                        break
                    }
                }
            }
            console.log(expandedRowKeys, 'expandedRowKeys1')
            this.expandedRowKeys = expandedRowKeys
        },
        customRow(record) {
            return {
                attrs: {
                    title: '拖曳更新上级行政区划',
                    draggable: true, // 设置拖拽属性
                },
                style: {
                    cursor: 'pointer',
                },
                on: {
                    // 双击
                    dblclick: event => {},
                    // 开始拖拽
                    dragstart: event => {
                        const ev = event || window.event
                        ev.stopPropagation()
                        // 得到源数据 dragRow
                        this.sourceRow = record
                        console.log(this.sourceRow, 'this.sourceObj')
                    },
                    // 拖动元素经过的元素
                    dragover: event => {
                        const ev = event || window.event
                        ev.preventDefault()
                        // 还原之前经过节点的样式
                        this.hoverNode && (this.hoverNode.className = '')
                        // 只能跨级移动
                        if (this.sourceRow.parentId === record.parentId) {
                            console.log('只能跨级移动')
                            return
                        }
                        // 不能被拖进子孙级
                        if (getPIds(this.tableData, record.id).includes(this.sourceRow.id)) {
                            console.log('不能被拖进子孙级')
                            return
                        }
                        // parent不能为空
                        if (!record.parentId) {
                            console.log('parent不能为空')
                            return
                        }
                        // 给当前经过节点设置样式
                        this.hoverNode = document.querySelector(
                            `tr[data-row-key=id-${record.id}--parentId-${record.parentId}]`,
                        )
                        if (record.recordIndex > this.sourceRow.recordIndex) {
                            // 源在下 **
                            this.hoverNode.className = 'drop-over-downward'
                        }
                        if (record.recordIndex < this.sourceRow.recordIndex) {
                            // 源在上
                            this.hoverNode.className = 'drop-over-upward'
                        }
                    },
                    // 鼠标松开
                    drop: event => {
                        const ev = event || window.event
                        ev.stopPropagation()
                        this.hoverNode && (this.hoverNode.className = '')
                        if (this.sourceRow.id === record.id) {
                            return
                        }
                        // parent不能为空
                        if (!record.parentId) {
                            console.log('parent不能为空')
                            return
                        }
                        // 只能跨级移动
                        if (this.sourceRow.parentId === record.parentId) {
                            return
                        }
                        // 不能被拖进子孙级
                        if (getPIds(this.tableData, record.id).includes(this.sourceRow.id)) {
                            return
                        }
                        // 得到目标数据 hoverRow
                        this.targetRow = record
                        console.log(this.targetRow, 'this.targetObj')
                        this.moveRow()
                    },
                },
            }
        },
        moveRow() {
            // 拖曳更新上级行政区划
            const exchange = list => {
                const targetRow = this.targetRow
                const sourceRow = this.sourceRow
                let sourceFind = false
                let targetFind = false
                for (let index = list.length - 1; index >= 0; index--) {
                    const { id, children, parentId, recordIndex } = list[index]
                    if (id === targetRow.id && !targetFind) {
                        console.log('找到目标', id, index)
                        targetFind = true
                        let targetIndex = index
                        if (recordIndex > this.sourceRow.recordIndex) {
                            // 源在下 **
                            targetIndex = index + 1
                        }
                        // 将源插入到目标并设置parentId
                        list.splice(
                            targetIndex,
                            0,
                            Object.assign(
                                { ...sourceRow },
                                {
                                    parentId,
                                },
                            ),
                        )
                    }
                    if (id === sourceRow.id && !sourceFind) {
                        console.log('找到源', id)
                        sourceFind = true
                        // 删除源
                        list.splice(index, 1)
                    }
                    if (!sourceFind || !targetFind) {
                        if (children?.length) {
                            exchange(children)
                        }
                    }
                }
            }
            const tableData = cloneDeep(this.tableData)
            exchange(tableData)
            // 执行更新
            const hide = this.$message.loading('正在更新...', 0)
            const { name, code, abbreviation, id } = this.sourceRow
            this.$apiReq.main
                .updateArea({
                    name,
                    code,
                    abbreviation,
                    parentId: this.targetRow.parentId,
                    id,
                })
                .then(() => {
                    this.tableData = [...this.formatTable(tableData)]
                    this.$message.success('更新成功', 2.5)
                })
                .finally(() => {
                    hide()
                })
        },
        formatTable(tableData) {
            let num = 0
            const customSomeKey = (list, level) => {
                list.forEach(item => {
                    item.level = level + 1
                    item.recordIndex = num++ // recordIndex用于判断拖曳元素 源与目标的位置
                    if (item.children?.length) {
                        customSomeKey(item.children, item.level)
                    }
                })
            }
            customSomeKey(tableData, -1)
            console.log(tableData, 'tableData')
            return tableData
        },
        buildTree(data, level, parentId) {
            let res = []

            if (parentId) {
                res = data.filter(n => n.areaLevel == level && n.parentId == parentId)
            } else {
                res = data.filter(n => n.areaLevel == level)
            }

            res = res.sort((a, b) => a.code - b.code)

            res.forEach((n, i) => {
                let innerChildren = this.buildTree(data, level + 1, n.id)

                if (innerChildren && innerChildren.length) {
                    n.children = innerChildren
                    n.leaf = false
                } else {
                    n.leaf = true
                }

                n.sn = i + 1
                n.parent = data.filter(n => n.id == parentId)[0]
            })

            return res
        },
    },
}
</script>

<style lang="scss" scoped>
/deep/ .drop-over-downward td {
    padding-bottom: 46px !important;
    border-bottom: 2px dashed #1890ff !important;
}

/deep/ .drop-over-upward td {
    padding-top: 46px !important;
    border-top: 2px dashed #1890ff !important;
}

/deep/ .tr-expand-icon {
    font-size: 16px !important;
    // transform: translateY(3px);
}
</style>
